package com.manager.filter;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.manager.util.CONSTANT;
import com.manager.util.CharUtil;
import com.manager.util.Log;

public class SecurityFilter implements Filter {
	public void destroy() {
		
	}

	public void doFilter(ServletRequest srequest, ServletResponse sresponse, FilterChain filterChain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest)srequest;
		HttpServletResponse response = (HttpServletResponse)sresponse;
		
		String requestUrl = request.getRequestURI();
		//取最后一个分隔符"/"之后的请求字串
		requestUrl = requestUrl.substring(requestUrl.lastIndexOf("/") + 1, requestUrl.length());
		String basePath = request.getContextPath();//上下文根路径
		/*
		 * 说明：
		 * 1:如果<context path=""></context>，则此处basePath: ""， 而页面上basePath: ""
		 * 3:如果<context path="/manager"></context>，则此处basePath: "/manager"，而页面上basePaht: "/manager"
		 * 结论：basePath与path的值是一致的，这两种方式也是推荐方式
		 */
		
		Log.info("requestUrl:" + requestUrl);
		Log.info("basePath:" + basePath);
		
//		if(true){
		if(checkUrl(requestUrl)){//放行, 永远不需要验证的
			filterChain.doFilter(srequest, sresponse);
		}else{//禁止
			Object obj = request.getSession().getAttribute(CONSTANT.SESSION_KEY);
			if(obj != null){//已登录
				if(this.checkUrlSuffix(requestUrl)){//禁止
					this.sendRedirectByJavascript("firewall.jsp", "msg=" + CharUtil.encodeURL("Permissions Beyond"), request, response);
				}else{//放行
					filterChain.doFilter(srequest, sresponse);
				}
			}else{//未登录
				this.sendRedirectByJavascript("firewall.jsp", "msg=" + CharUtil.encodeURL("Identity Is Not Certified"), request, response);
			}
		}
		
		return;
	}
	
	public void init(FilterConfig arg0) throws ServletException {
		
	}
	
	//辅助函数, 该URL是否是永久放行的URL
	private boolean checkUrl(String requestUrl){
		//永远放行的URL
		boolean flag = false;
		for(int i = 0; i < CONSTANT.GREEN_URL.length; i++){
			//需要放行的URL
			if(requestUrl.equals(CONSTANT.GREEN_URL[i])){
				flag = true;
				Log.info(">>>放行");
				break;
			}
		}
		return flag;
	}
	
	//辅助函数, 该URL后缀是否是禁止的URL后缀
	private boolean checkUrlSuffix(String requestUrl){
		requestUrl = requestUrl.substring(requestUrl.lastIndexOf("."), requestUrl.length());
		//是否要访问的URL
		boolean flag = false;
		for(int i = 0; i < CONSTANT.RED_URL_SUFFIX.length; i++){
			if(requestUrl.equals(CONSTANT.RED_URL_SUFFIX[i])){//禁止
				flag = true;
				Log.info(">>>禁止");
				break;
			}
		}
		return flag;
	}
	
	//用javascript进行最顶层页面的跳转
	private void sendRedirectByJavascript(String url, String param, HttpServletRequest request, HttpServletResponse response){
		PrintWriter p = null;
		
		try{
			p = response.getWriter();
			
			response.setContentType("text/html; charset=UTF-8");
			
			//组合要输出的javascript语句
			StringBuffer sb = new StringBuffer();
			String basePath = (String)request.getSession().getServletContext().getAttribute("basePath");
			sb.append("<script type=\"text/javascript\">");
				sb.append("alert('Log Out OR Identity Is Not Certified');");
				sb.append("top.window.location.href = \"");
				sb.append(basePath + "/" + url + "?" + param);
				sb.append("\";");
			sb.append("</script>");
			
			p.print(sb.toString());
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			p.flush();
			p.close();
		}
	}
}
